package com.stu.config;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.AuthorizationException;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Path;
import java.util.List;
import java.util.Set;

/**
 * @Author: MI
 * @Date: 2021/8/25/22:23
 * @Description:
 */
@Slf4j
//@ControllerAdvice(annotations = {Controller.class, RestController.class})
@RestControllerAdvice(annotations = {Controller.class, RestController.class})
public class GlobalExceptionHandler {

    private ObjectError vo;

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public JSONObject defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
        JSONObject jsonObject = new JSONObject();
        log.error("发生异常", e);
        jsonObject.put("error", e.getMessage());
        return jsonObject;
    }

    @ExceptionHandler(value = AuthorizationException.class)
    @ResponseBody
    public JSONObject authorizationException(HttpServletRequest req, Exception e) throws Exception {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("error", e.getMessage());
        jsonObject.put("msg", "权限不足");
        return jsonObject;
    }

    /**
     * 捕获参数异常
     * MissingServletRequestParameterException 校验普通参数
     *
     * @param exception MethodArgumentNotValidException BindException
     * @return
     */
    @ExceptionHandler(value = {MethodArgumentNotValidException.class})
    @ResponseBody
    public JSONObject argumentException(MethodArgumentNotValidException exception) {
        String resut = "";
        //查看MethodArgumentNotValidException类可以发现,异常的信息在BindingResult下List<ObjectError>中
        //我这里取第一条的信息进行展示,可根据实际项目情况自行修改
        //getDefaultMessage()获取的信息就是我们RequestVerificationCode中的message部分
        BindingResult bindingResult = exception.getBindingResult();
        List errorList = CollectionUtil.newArrayList();
        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            String msg = String.format("%s%s；", fieldError.getField(), fieldError.getDefaultMessage());
            errorList.add(msg);
        }
        //自定义的返回类,可根据实际项目情况自行修改
        return new JSONObject().fluentPut("validateErr", errorList);
    }

    /**
     * 处理单个参数校验失败抛出的异常
     */
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseBody
    public JSONObject ParamsException(ConstraintViolationException e) {

        List errorList = CollectionUtil.newArrayList();
        Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
        for (ConstraintViolation<?> violation : violations) {
            StringBuilder message = new StringBuilder();
            Path path = violation.getPropertyPath();
            String[] pathArr = StrUtil.splitToArray(path.toString(), '.');
            String msg = message.append(pathArr[1]).append(violation.getMessage()).toString();
            errorList.add(msg);
        }
        return new JSONObject().fluentPut("validateParamErr", errorList);
    }
}
